/* 
    工具类函数
*/
/* 
    求范围之间的随机数
    @param {a} 范围下限
    @param {b} 范围上限
    @return 范围之间的随机数
*/
function getRandom(a, b) {
    return parseInt(Math.random() * (b - a + 1) + a)
}


/* 
    求随机颜色
    @return 随机颜色字符串
*/
function getColor() {
    return 'rgb(' + getRandom(0, 255) + ',' + getRandom(0, 255) + ',' + getRandom(0, 255) + ')'
}


/* 
    获取元素
    @param {selector}  选择器
    @param {context}  是在哪一个范围里面找 可选
    @return 获取到的某个或者某些元素
*/
function my$(selector,context){     
    context = context || document  
    if(selector.indexOf('#') === 0){
        // #id名
        return document.getElementById(selector.substring(1))  
    } 
    if(selector.indexOf('.') === 0){
        // 类名
        return context.getElementsByClassName(selector.substring(1))
    }
    return context.querySelectorAll(selector)
}



/* 
    获取/设置元素的 css 样式

*/
function css(ele,attr,value){
    // 可以通过 第三个参数是否传入 来判断是设置还是获取
    if(!value){
        return window.getComputedStyle ? window.getComputedStyle(ele)[attr] : ele.currentStyle[attr]
    }
    // 传了第三个参数 设置 
    ele.style[attr] = value 

}

/* 
    绑定事件
    @param {ele}  要绑定事件的元素
    @Parma {type} 事件类型
    @param {fn}  事件处理函数 
 */
function on(ele,type,fn){
    if(ele.addEventListener){
        if(type.indexOf('on') === 0){
            type = type.slice(2)
        }
        ele.addEventListener(type,fn)
    }else{
        if(type.indexOf('on') != 0){
            type = 'on' + type
        }
        ele.attachEvent(type,fn)
    }
}
/* 
    解绑事件
    @param {ele}  要绑定事件的元素
    @Parma {type} 事件类型
    @param {fn}  事件处理函数 
*/
function off(ele,type,fn){
    if(ele.removeEventListener){
        if(type.indexOf('on') === 0){
            type = type.slice(2)
        }
        ele.removeEventListener(type,fn)
    }else{
        if(type.indexOf('on') != 0){
            type = 'on' + type
        }
        ele.detachEvent(type,fn)
    }
}

/* 
    动画函数
    @param {ele} 要执行动画的元素
    @param {options} 多个属性组成的对象 值是终点值
    @param {duration}  运动经过的总的时间
    @param {fn} 动画执行完毕的回调函数
*/
function animate(ele,options,duration,fn){
    clearInterval(ele.timer)
    let start = {},range = {}
    for(let key in options){
        start[key] = parseInt(css(ele,key))
        range[key] = options[key] - start[key]
    }
    const startTime = new Date().getTime()
    ele.timer = setInterval(() => {
            let shijiancha = Math.min(new Date().getTime() - startTime,duration) 
            for(let attr in options){
                let result = range[attr] / duration * shijiancha + start[attr]
                result = attr === 'opacity' ? result : result + 'px'
                ele.style[attr] = result
            }
            if(shijiancha >= duration){
                clearInterval(ele.timer)
                fn && fn()
            }
    },10)
}

/* 
    淡入
*/
function fadeIn(ele,duration,fn){
    css(ele,'display','block')
    css(ele,'opacity','0')
    animate(ele,{opacity:1},duration,fn) 
}
/* 
    淡出
*/
function fadeOut(ele,duration,fn){
    css(ele,'display','block')
    css(ele,'opacity','1')
    animate(ele,{opacity:0},duration,fn) 
}

// 获取隐藏元素的 内容 + padding  (clientWidth)
function inWidth(ele){
    // 内容 + 左右 padding 
    return parseInt(css(ele,'width')) + parseInt(css(ele,'paddingLeft')) + parseInt(css(ele,'paddingRight'))
}

function inHeight(ele){
    // 内容 + 上下 padding 
    return parseInt(css(ele,'height')) + parseInt(css(ele,'paddingTop')) + parseInt(css(ele,'paddingBottom'))
}

// 获取隐藏元素的 内容 + padding + border (offsetWidth)
function outWidth(ele){
    // 内容 + 左右 padding 
    return parseInt(css(ele,'width')) + parseInt(css(ele,'paddingLeft')) + parseInt(css(ele,'paddingRight')) + parseInt(css(ele,'borderLeft')) + parseInt(css(ele,'borderRight'))
}

function outHeight(ele){
    // 内容 + 左右 padding 
    return parseInt(css(ele,'height')) + parseInt(css(ele,'paddingTop')) + parseInt(css(ele,'paddingBottom')) + parseInt(css(ele,'borderTop')) + parseInt(css(ele,'borderBottom'))
}